package com.lej.dataservice.club.http;

import android.text.TextUtils;

import com.lej.core.base.BaseApplication;
import com.lej.core.utils.KLog;
import com.lej.dataservice.club.http.base.HttpUrl;
import com.lej.dataservice.club.http.cookie.CookieJarImpl;
import com.lej.dataservice.club.http.cookie.store.PersistentCookieStore;
import com.lej.dataservice.club.http.interceptor.BaseInterceptor;
import com.lej.dataservice.club.http.interceptor.CacheInterceptor;
import com.lej.dataservice.club.http.interceptor.ErrorInterceptor;
import com.lej.dataservice.club.http.interceptor.EventInterceptor;
import com.lej.dataservice.club.http.interceptor.HeaderInterceptor;
import com.lej.dataservice.club.http.interceptor.ParamsInterceptor;
import com.lej.dataservice.club.http.interceptor.logging.Level;
import com.lej.dataservice.club.http.interceptor.logging.LoggingInterceptor;
import com.lej.stethomodule.StethoUtils;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import okhttp3.internal.platform.Platform;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * RetrofitClient封装单例类, 实现网络请求
 */
public class RetrofitClient {
    //超时时间
    private static final int DEFAULT_TIMEOUT = 20;
    //缓存时间
    private static final int CACHE_TIMEOUT = 10 * 1024 * 1024;
    //服务端根路径
    public static String baseUrl = HttpUrl.BASE_URL;

    private static Retrofit retrofit;

    private Cache cache = null;
    private File httpCacheDirectory;

    private static class SingletonHolder {
        private static final RetrofitClient INSTANCE = new RetrofitClient();
    }

    public static RetrofitClient getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private RetrofitClient() {
        this(baseUrl, null);
    }

    private RetrofitClient(String url, Map<String, String> headers) {
        BaseApplication application = BaseApplication.Companion.getInstance();
        if (TextUtils.isEmpty(url)) {
            url = baseUrl;
        }

        if (httpCacheDirectory == null) {
            httpCacheDirectory = new File(application.getCacheDir(), "lej_cache");
        }

        try {
            if (cache == null) {
                cache = new Cache(httpCacheDirectory, CACHE_TIMEOUT);
            }
        } catch (Exception e) {
            KLog.e("Could not create http cache", e);
        }
        OkHttpClient okHttpClient = getOkHttpClient(headers, application);
        retrofit = new Retrofit.Builder()
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(url)
                .build();
    }

    @NotNull
    public OkHttpClient getOkHttpClient(Map<String, String> headers, BaseApplication application) {
        HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory();
        //                .cache(cache)
        //构建者模式
        //是否开启日志打印
        //打印的等级
        // 打印类型
        // request的Tag
        // Response的Tag
        // 添加打印头, 注意 key 和 value 都不能是中文
        // 这里你可以根据自己的机型设置同时连接的个数和时间，我这里8个，和每个保持时间为10s
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .cookieJar(new CookieJarImpl(new PersistentCookieStore(application)))
//                .cache(cache)
                .addInterceptor(new BaseInterceptor(headers))
                .addInterceptor(new CacheInterceptor())
                .addInterceptor(new HeaderInterceptor())
                .addInterceptor(new ParamsInterceptor())
                .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
                .addInterceptor(new EventInterceptor())
                .addInterceptor(new ErrorInterceptor())
                .addInterceptor(new LoggingInterceptor
                        .Builder()//构建者模式
                        .loggable(application.isDebug()) //是否开启日志打印
                        .setLevel(Level.BASIC) //打印的等级
                        .log(Platform.INFO) // 打印类型
                        .request("Request") // request的Tag
                        .response("Response")// Response的Tag
                        .addHeader("log-header", "I am the log request header.") // 添加打印头, 注意 key 和 value 都不能是中文
                        .build()
                );
        if (BaseApplication.Companion.getInstance().isDebug())
            builder.addNetworkInterceptor(StethoUtils.configureInterceptor());
        return builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .connectionPool(new ConnectionPool(8, 15, TimeUnit.SECONDS))
                // 这里你可以根据自己的机型设置同时连接的个数和时间，我这里8个，和每个保持时间为10s
                .build();
    }

    /**
     * create you ApiService
     * Create an implementation of the API endpoints defined by the {@code service} interface.
     */
    public <T> T create(final Class<T> service) {
        if (service == null) {
            throw new RuntimeException("Api service is null!");
        }
        return retrofit.create(service);
    }
}
